/*
 * Hibiscus is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 3 of the License,
 * or (at your option) any later version.
 *
 * Hibernate is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Hibiscus; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 *
 * Copyright (C) 2011 Tetete - http://tetete.hu.
 */
package hu.tetete.hibiscus.userfile;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.os.Environment;

import hu.tetete.hibiscus.model.Taxon;

/**
 * TODO javadoc.
 *
 * @author envagyok
 */
public class UserfileUtil {

    /**
     * The name of the directory which contains the files. e.g. photos, notes etc.
     */
    private static final String HIBISCUS_DIR_NAME = "hibiscus";

    /**
     * Returns root directory of the application on external storage.
     * If it doesn't exist, the method will create a new directory.
     * If any problem occurs an IOException will be thrown.
     * @return The main directory of the application.
     * @throws IOException If any error occurs.
     */
    public static File getHibiscusDir() throws IOException {
        final String storageState = Environment.getExternalStorageState();

        /* If no SD card we will show an error message */
        if(!storageState.equals(Environment.MEDIA_MOUNTED)) {
            throw new IOException(); //TODO throw an own exception.
        }

        final File hibiscusDir = new File(Environment.getExternalStorageDirectory(), HIBISCUS_DIR_NAME);
        if (hibiscusDir.exists()) {
            if (!hibiscusDir.isDirectory()) {
                throw new IOException(HIBISCUS_DIR_NAME + " exist and it's not a directory");
            }
        } else {
            if (!hibiscusDir.mkdirs()) {
                throw new IOException("Couldn't create " + HIBISCUS_DIR_NAME + " directory on external storage.");
            }
        }
        return hibiscusDir;
    }

    /**
     * Returns the taxon's directory. This directory could be not created. Before use it, check that
     * @param taxon The taxon
     * @return The taxon's directory.
     * @throws IOException An error occurs.
     */
    public static File getTaxonDir(final Taxon taxon) throws IOException {
        return getTaxonDir(taxon.getId());
    }

    /**
     * Returns the taxon's directory. This directory could be not created. Before use it, check that.
     * @param taxon The identifier of taxon
     * @return The taxon's directory.
     * @throws IOException An error occurs.
     */
    public static File getTaxonDir(final Long taxonId) throws IOException {
        final File hibiscusDir = getHibiscusDir();
        final File taxonDir = new File(hibiscusDir, String.valueOf(taxonId));
        if (taxonDir.exists()) {
            if (!taxonDir.isDirectory()) {
                throw new IOException("I found a file instead of a director for taxon identified by " + taxonId);
            }
            if (!taxonDir.canRead()) {
                throw new IOException("The directory of taxon identified by " + taxonId + " is existing but not readable. ");
            }
        }
        return taxonDir;
    }

    /**
     * Returns the file of the main photo of the taxon.
     * @param taxon The taxon
     * @return The file object of the main photo if it exists, otherwise <tt>null</tt>
     */
    public static File getTaxonPhoto(final Taxon taxon) {
        if (taxon == null || taxon.getPhoto() == null) {
            return null;
        }
        try {
            final File taxonDir = getTaxonDir(taxon);
            if (!taxonDir.exists()) {
                return null;
            }
            final File photo = new File(taxonDir, taxon.getPhoto());
            if (photo.exists() && photo.canRead()) {
                return photo;
            }
            return null;
        } catch (final IOException e) {
            return null;
        }
    }



    private UserfileUtil() {
        throw new UnsupportedOperationException("This is a utils class. Do not create instance.");
    }

    /**
     * @param tempPhoto
     * @param taxonId
     * @return
     * @throws IOException
     */
    public static String savePhoto(final File tempPhoto, final Long taxonId) throws IOException {
        final File taxonDir = getTaxonDir(taxonId);
        if (!taxonDir.exists()) {
            if (!taxonDir.mkdirs()) {
                throw new IOException(); //TODO more information.
            }
        }
        final File permantentPhoto = new File(taxonDir, "taxonphoto_" + String.valueOf(System.currentTimeMillis()) + ".jpg");
        copy(tempPhoto, permantentPhoto);

        return permantentPhoto.getName();
    }

    private static void copy(final File src, final File dst) throws IOException {
        final InputStream  in  = new FileInputStream(src);
        final OutputStream out = new FileOutputStream(dst);

        // Transfer bytes from in to out
        final byte[] buf = new byte[1024];
        int len;
        while ((len = in.read(buf)) > 0) {
            out.write(buf, 0, len);
        }
        in.close();
        out.close();
    }
}
